/**
 * @module 输出的界面保存备用 下次访问先检测是否存在，若存在直接取用
 */
const {md5} = require("request/lib/helpers");
const fs = require("fs");
const path = require("path");
const htmlMini = require('html-minifier');

const config = require('../../config/index')
const logController = require('../logController/index')


class CacheController {
    cacheDir = config.cache.cacheDir || path.join(__dirname, '../../', './cache');
    isCached = config.cache.isCached || false
    /**
     * @function checkCacheDir
     * @desc 检测并保持缓存文件夹的存在
     * @returns {void|boolean}
     */
    checkCacheDir = () => {
        if (!this.isCached) return void 0
        if (fs.existsSync(this.cacheDir)) return (() => {
            logController.addLog({content: `检测${this.cacheDir}已存在，结束${this.checkCacheDir.name}的运行`})
            return fs.existsSync(this.cacheDir)
        })();
        logController.addLog({content: "检测" + this.cacheDir + "不存在,已重新创建"})
        return fs.mkdirSync(this.cacheDir, {mode: 0o777})
    }

    constructor(isCached) {
        this.checkCacheDir()
    }

    /**
     * @desc 负责将传入的字符串压缩后保存到 路径为 文件名
     * @param viewPath 指定模板路径
     * @param pageData
     */
    saveHTMLtoCache = (viewPath = 'news/chunwenzi/detail.html', pageData) => {
        return (req, res, next) => {
            let {originalUrl, params, query} = req
            if (!pageData) {
                pageData = pageData || {originalUrl, params, query}
            }

            res.render(viewPath, pageData, (err, html) => {
                try {
                    let pathName = req.originalUrl, fileName = md5(pathName);
                    if (err) {
                        logController.addLog({content: err.message})
                        return next(new Error(err.message))
                    }
                    /**
                     * 要实现将html中随机链接赋值到href属性值中
                     *
                     */

                    html = html.replaceAll('__random_link__', substring => Math.random())
                    this.isCached && this.minifyHtmlAndSaveToFile(html, this.cacheDir + '/' + fileName)
                    return res.send(html)
                } catch (e) {
                    return next(new Error(err.message))
                }

            })
        }
    }


    /**
     * 一个检测缓存文件的函数
     * @param req
     * @param res
     * @param next
     * @returns {string}
     */
    getHTMLtoCache = (req, res, next) => {
        try {
            let fileName = md5(req.originalUrl)
            let path = this.cacheDir + '/' + fileName
            if (this.isCached && fs.existsSync(path)) {
                res.status(200)
                res.header('type', `cache-${fileName}`)
                res.send(fs.readFileSync(path, {encoding: 'utf8'}).toString())
                return void 0
            }
        } catch (e) {
            logController.addLog({content: e.message})
        }
        next()
    }

    minifyHtmlAndSaveToFile(inputHtml, outputFile) {
        const htmlMiniConfig = {
            collapseWhitespace: true,
            removeComments: true,
            removeRedundantAttributes: true,
            removeScriptTypeAttributes: true,
            removeStyleLinkTypeAttributes: true,
            removeOptionalTags: true,
            useShortDoctype: true,
            minifyJS: true,
            minifyCSS: true,
        }
        // 压缩HTML字符串
        const minifiedHtml = htmlMini.minify(inputHtml, htmlMiniConfig);
        try {
            // 将压缩后的HTML字符串写入文件
            fs.writeFileSync(outputFile, minifiedHtml, {encoding: "utf8"});
            logController.addLog({content: 'HTML minified and saved to file:' + outputFile})
        } catch (e) {
            logController.addLog({content: 'Error writing file:' + e.message})
            return void 0
        }
        return true
    }
}

module.exports = cacheController = new CacheController()